package com.qjc.demo.strategyAndFactory.context;

import cn.hutool.core.util.ObjectUtil;
import com.qjc.demo.strategyAndFactory.enums.StrategyEnum;
import com.qjc.demo.strategyAndFactory.service.IStrategyService;
import com.qjc.demo.strategyAndFactory.service.impl.StrategyDefaultServiceImpl;
import com.qjc.demo.strategyAndFactory.service.impl.StrategyType;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * 策略类选取
 *
 * @ClassName: StrategyContext
 * @Author: qjc
 * @Date: 2023/5/9 17:46
 */
@Component
public class StrategyContext implements ApplicationContextAware {

    @Resource
    private ApplicationContext applicationContext;
    @Resource
    private StrategyDefaultServiceImpl strategyDefaultService;

    private static Map<String, Class<? extends IStrategyService>> strategyMap = new HashMap<>();

    @Override
    public void setApplicationContext(@Nullable ApplicationContext applicationContext) {
        Map<String, Object> agentTypeMap = applicationContext.getBeansWithAnnotation(StrategyType.class);
        agentTypeMap.forEach((k, v) -> {
            if (v instanceof IStrategyService) {
                Class<? extends IStrategyService> strategyServiceClass = ((IStrategyService) v).getClass();
                StrategyEnum[] strategyEnums = strategyServiceClass.getAnnotation(StrategyType.class).value();
                for (StrategyEnum strategyEnum : strategyEnums) {
                    strategyMap.put(strategyEnum.getCode(), strategyServiceClass);
                }
            }
        });
    }

    /**
     * 使用工厂模式根据策略类型选取不同的策略
     *
     * @Author: qjc
     * @Date: 2023/5/9 18:24
     * @Param: strategyType 策略类型
     * @Return:
     */
    public IStrategyService getStrategyService(String strategyType) {
        Class<? extends IStrategyService> strategyServiceClass = strategyMap.get(strategyType);
        if (ObjectUtil.isNull(strategyServiceClass)) {
            return strategyDefaultService;
        }
        return applicationContext.getBean(strategyServiceClass);
    }

}
